//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.0
#include "nfc_spi_driver.h"
#include <string.h>

typedef enum
{
    Idle = 0,//空闲
    Busy = 1,//忙碌
    Success = 0,//无错误码
	Error   = 1,//通信错误
}WHT_State_enum;

static WHT_State_enum Idle_State = Idle;
static WHT_State_enum Error_State;



/**********************驱动初始化配置*********************/
static SemaphoreHandle_t WHT_TRx_xSemaphore;//二值信号量句柄
static WHT_SPI_Cache_t WHT_Cache;
static volatile unsigned int* WHT_Soft_NSS;

static void WHT_Set_NSS_State_Callback(WHT_SPI_IO_State_enum state)
{
	*WHT_Soft_NSS = state;
}
static void WHT_TRx_Idle_IT_Callback(void)
{
    BaseType_t xHigherPriorityTaskWoken;

    xSemaphoreGiveFromISR(WHT_TRx_xSemaphore, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
static void WHT_Driver_Init(void)
{
    if (WHT_SPI_BUS1_Init() != 0)
    {
        /* 总线初始化失败 */
        return;
    }
	if (WHT_SPI_BUS1->Config.NSS == Soft_NSS)//配置片选引脚
	{
		WHT_GPIO_BSP.WHT_Set_Clock(NFC_NSS_GPIO_PORT, ENABLE);
		WHT_GPIO_BSP.WHT_Set_State(NFC_NSS_GPIO_PORT, NFC_NSS_GPIO_PIN, Hig);
		WHT_GPIO_BSP.WHT_Set_Mode(NFC_NSS_GPIO_PORT, NFC_NSS_GPIO_PIN, Mode_Out_PP);
		WHT_GPIO_BSP.WHT_Config_Bit_Output(NFC_NSS_GPIO_PORT, NFC_NSS_GPIO_PIN, &WHT_Soft_NSS);
	}
	WHT_Cache.Set_NSS_State_CB = WHT_Set_NSS_State_Callback;
	WHT_Cache.TRx_Finish_IT_CB = WHT_TRx_Idle_IT_Callback;

    WHT_TRx_xSemaphore = xSemaphoreCreateBinary();
}
/**********************驱动初始化配置*********************/


/************************** start read & write ********************************/
static void WHT_Auto_Select_Handle(uint32_t count)
{
    TickType_t Tick_Count = 0;
	
	extern uint32_t SystemCoreClock;//out system_stm32f10x.c
	switch (WHT_SPI_BUS1->Config.Clock_Div)
	{
	case APBx_DIV2:  Tick_Count = count * WHT_SPI_BUS1->Config.Bit_Wide *   2 / (SystemCoreClock / 1000) / portTICK_RATE_MS; break;//单位ms/Tick;
	case APBx_DIV4:  Tick_Count = count * WHT_SPI_BUS1->Config.Bit_Wide *   4 / (SystemCoreClock / 1000) / portTICK_RATE_MS; break;//单位ms/Tick;
	case APBx_DIV8:  Tick_Count = count * WHT_SPI_BUS1->Config.Bit_Wide *   8 / (SystemCoreClock / 1000) / portTICK_RATE_MS; break;//单位ms/Tick;
	case APBx_DIV16: Tick_Count = count * WHT_SPI_BUS1->Config.Bit_Wide *  16 / (SystemCoreClock / 1000) / portTICK_RATE_MS; break;//单位ms/Tick;
	case APBx_DIV32: Tick_Count = count * WHT_SPI_BUS1->Config.Bit_Wide *  32 / (SystemCoreClock / 1000) / portTICK_RATE_MS; break;//单位ms/Tick;
	case APBx_DIV64: Tick_Count = count * WHT_SPI_BUS1->Config.Bit_Wide *  64 / (SystemCoreClock / 1000) / portTICK_RATE_MS; break;//单位ms/Tick;
	case APBx_DIV128:Tick_Count = count * WHT_SPI_BUS1->Config.Bit_Wide * 128 / (SystemCoreClock / 1000) / portTICK_RATE_MS; break;//单位ms/Tick;
	case APBx_DIV256:Tick_Count = count * WHT_SPI_BUS1->Config.Bit_Wide * 256 / (SystemCoreClock / 1000) / portTICK_RATE_MS; break;//单位ms/Tick;
	}
	if (Tick_Count)
    {
        WHT_SPI_BUS_OPS.Read_Write_IT(WHT_SPI_BUS1, &WHT_Cache);
    }
	else
    {
        WHT_SPI_BUS_OPS.Read_Write(WHT_SPI_BUS1, &WHT_Cache);
    }
	
    if (WHT_SPI_BUS1->Mutex == SPI_Unlock)//传输结束
    {
		if (WHT_SPI_BUS1->State != SPI_No_Error)
			Error_State = Error;
    }
    else
        xSemaphoreTake(WHT_TRx_xSemaphore, portMAX_DELAY);//等待信号量
}
static void WHT_Write_Data(uint8_t* const input_buf, uint32_t count)
{
	while (WHT_SPI_BUS1->Mutex == SPI_Lock)//等待互斥锁成功打开
		vTaskDelay(1);
	WHT_Cache.Dir = SPI_WO;
	WHT_Cache.Buffer_Count = count;
	WHT_Cache.Tx_Buffer = input_buf;
	WHT_Cache.Rx_Buffer = NULL;
    WHT_Auto_Select_Handle(count);

}
static void WHT_Read_Data(uint8_t* const input_buf,uint8_t* const output_buf, uint32_t count)
{
	while (WHT_SPI_BUS1->Mutex == SPI_Lock)//等待互斥锁成功打开
		vTaskDelay(1);
	WHT_Cache.Dir = SPI_RW;
	WHT_Cache.Buffer_Count = count;
	WHT_Cache.Tx_Buffer = input_buf;
	WHT_Cache.Rx_Buffer = output_buf;
    WHT_Auto_Select_Handle(count);
}
/************************** end read & write **********************************/




//传输数据 返回0正常 -1错误
int NFC_SPI_Start_TRx_Transmit(uint8_t* const input_buf, uint8_t* const output_buf, uint32_t count)
{
    if (input_buf == NULL)
    {
        return -1;
    }

	while (Idle_State == Busy)//等待空闲
		vTaskDelay(1);
    Idle_State = Busy;//忙碌
    Error_State = Success;

    if (output_buf == NULL)
    {
        WHT_Write_Data(input_buf, count);
    }
    else
    {
        WHT_Read_Data(input_buf, output_buf, count);
    }
    
    Idle_State = Idle;//空闲
    return Error_State == Success ? 0 : -1;
}

void NFC_SPI_Init_Config(void)
{
    WHT_Driver_Init();
}
